package com.pan.handle.req.strategy;

import com.pan.entity.HumbleHttpRequest;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class TestStrategy {
    //Note: This class instance is included status
    //这里已经包含了状态了，不知道有没有什么问题
    //用的时候请注意
    private byte[] buf = new byte[4096];
    int size = 0;
    public void appendBuffer(byte[] buf,int start, int end){
        for (int i = start;i<end;i++){
            if (size == this.buf.length) return;
            this.buf[size++] = buf[i];
        }
    }
                                                            //((?i)get|post|put|delete)\s/.*\s((?i)https?)/\d\.\d\r\n(\w+(-\w+)*?:\s.*\r\n)+\r\n
    private Pattern httpHeaderPattern = Pattern.compile("((?i)get|post|put|delete)\\s/.*\\s((?i)https?)/\\d\\.\\d\r\n(\\w+(-\\w+)*?:\\s.*\r\n)+\r\n");
    public boolean isComplete(){
        String currentMessage = new String(buf,0,size);
        if (httpHeaderPattern.matcher(currentMessage).find()){
            return true;
        } else {return false;}
    }
    private void clear(){
        size = 0;
    }
    Pattern attributePattern = Pattern.compile("(.*?):\\s(.*?)\r\n");
    public HumbleHttpRequest getResult(){
        HumbleHttpRequest request = new HumbleHttpRequest();
        String currentMessage = new String(buf,0,size);
        Matcher httpMc = httpHeaderPattern.matcher(currentMessage);
        if (!httpMc.find()) throw new RuntimeException("Not Such HttpMessage");
        String httpMessage = httpMc.group();
        //index of the join symbol for first line and header
        String fjhSign = "\r\n";
        int fjhIndex = httpMessage.indexOf(fjhSign);

        //This is the Http first line processing code
        String firstLine = httpMessage.substring(0,fjhIndex);
        Pattern firstPattern = Pattern.compile("((?i)get|post|put|delete)\\s(/.*)\\s((?i)https?/\\d\\.\\d)");
        Matcher flMc = firstPattern.matcher(firstLine);
        if (!flMc.find()&&flMc.groupCount()!=3) throw new RuntimeException("first line of the http message error");
        request.setMethod(flMc.group(1));//Method
        request.setUrl(flMc.group(2));//url //flMc.find(3);//http version


        //This is the parameter processing code
        String url = request.getUrl();
        int pi = url.indexOf("?");//parameter sign index
        if (pi!=-1){
            String pnv = url.substring(pi+1);//parameter name and parameter value
            String[] pnvArr = pnv.split("&");
            for (String nv : pnvArr) {
                int njvi = nv.indexOf("=");//index of the join symbol for name and value
                String pn = nv.substring(0,njvi);
                String pv = nv.substring(njvi+1);
                request.addUrlParameter(pn,pv);
            }
        }

        //This is the Http Header processing code
        String header = httpMessage.substring(fjhIndex+fjhSign.length());
        Matcher attrMc = attributePattern.matcher(header);
        for (;attrMc.find();){
            if (attrMc.groupCount() != 2 ) throw new RuntimeException("struct of the http header error: "+attrMc.group());
            String attrName = attrMc.group(1);
            String attrVal = attrMc.group(2);
            request.addHttpAttribute(attrName,attrVal);
        }


        //todo: 修改这段代码，这里的逻辑是不完善的，现在还不能确定body是否传输完成。
        //todo: Modify this code; the here logic is incomplete, and it is currently not possible to determine whether the http body has been fully transmitted
        //This is the Http Body processing code
        if (request.getHttpAttribute().containsKey("Content-Length")) {
            String clStr = request.getHttpAttribute().get("Content-Length");
//            int len = Integer.parseInt(clStr);
            //十分不可靠
            //very unreliable
            Pattern bodyPattern  = Pattern.compile("(?<=\r\n\r\n).*");
            Matcher bodyMc = bodyPattern.matcher(currentMessage);
            bodyMc.find();
            String body = bodyMc.group();
            request.setBody(body);
        }
        return request;
    }
}
